﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;

namespace Common.OpenXml
{
	/// <summary>
	/// Encapsulates the functionality of a workbook.
	/// </summary>
	public class Workbook : PackagePartBase
	{
		private Workbook(PackageHelper package, Uri uri)
			: base(package, uri)
		{ }

		/// <summary>
		/// Opens an existing workbook part from the package.
		/// </summary>
		/// <param name="package">The package containing the workbook part</param>
		/// <returns>A new instance of a Workbook object.</returns>
		public static Workbook Open(PackageHelper package)
		{
			// create the uri
			Uri uri = new Uri("/xl/workbook.xml", UriKind.Relative);

			// return the new object
			return new Workbook(package, uri);
		}

		/// <summary>
		/// Adds a pivot cache definition to the workbook
		/// </summary>
		/// <param name="pivotCacheDefinition">The PivotCacheDefinition to add.</param>
		/// <returns>The cache id defined for the item in the workbook.</returns>
		public int AddPivotCacheDefinition(PivotCacheDefinition pivotCacheDefinition)
		{
			// create the relationship
			string relId =
				base.Package.CreateInternalRelationship(base.Uri,
					pivotCacheDefinition.Uri,
					"http://schemas.openxmlformats.org/officeDocument/" +
					"2006/relationships/pivotCacheDefinition");

			// verify that the pivotCaches element exists in the workbook
			XPathNavigator pivotCachesNav =
				PackageData.CreateNavigator().SelectSingleNode(
					"x:workbook/x:pivotCaches",
					Namespaces.NamespaceManager);
			if (pivotCachesNav == null)
			{
				XmlElement pivotCachesElement =
					PackageData.CreateElement("pivotCaches",
					Namespaces.SpreadsheetML);
				PackageData.DocumentElement.AppendChild(
					pivotCachesElement);
				pivotCachesNav = pivotCachesElement.CreateNavigator();
			}

			// calculate a new pivot cache id
			int newCacheId = 0;
			XPathNodeIterator cacheIdsIt =
				PackageData.CreateNavigator().Select(
					"x:workbook/x:pivotCaches/x:pivotCache/@cacheId",
					Namespaces.NamespaceManager);
			foreach (XPathNavigator cacheId in cacheIdsIt)
				if (int.Parse(cacheId.Value) > newCacheId)
					newCacheId = int.Parse(cacheId.Value);
			newCacheId++; // increment it to get the next id

			// append the new pivot cache entry
			using (XmlWriter writer = pivotCachesNav.AppendChild())
			{
				// add the pivot cache element
				// <pivotCache cacheId="1" r:id="rid1" />
				writer.WriteStartElement("pivotCache",
					Namespaces.SpreadsheetML);
				writer.WriteAttributeString("cacheId",
					newCacheId.ToString());
				writer.WriteAttributeString(Prefixes.Relationships, "id",
					Namespaces.Relationships, relId);
				writer.WriteEndElement();
			}

			// return the new cache id
			return newCacheId;
		}
	}
}
